﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace QueuesAndStacks.MyCircularQueue
{
    class MainProject
    {
        static void Main(string[] args)
        {
            MyCircularQueue obj = new MyCircularQueue(1);
            obj.EnQueue(1);
            obj.EnQueue(2);
            obj.Rear();
            obj.EnQueue(9);
            obj.DeQueue();
            obj.Front();

            //obj.Rear();
            //obj.IsFull();
            //obj.DeQueue();
            //obj.EnQueue(4);
            //obj.Front();
            //obj.Rear();
            //obj.IsEmpty();
        }

        //1.当为0的时候不能++
        public class MyCircularQueue
        {
            private int[] m_Data;
            private int m_Pre;
            private int m_Last;
            private bool m_IsHave = false;
            public MyCircularQueue(int k)
            {
                m_Data = new int[k];
                m_Pre = 0;
                m_Last = 0;
            }
            //last常驻状态为有
            public bool EnQueue(int value)
            {
                if (IsFull()) return false;
                if (!IsEmpty()) m_Last++;
                else m_IsHave = true;
                int index = m_Last % (m_Data.Length);
                m_Data[index] = value;
                ClearIndex();
                return true;
            }

            private void ClearIndex()
            {
                if (m_Last >= m_Data.Length && m_Pre >= m_Data.Length)
                {
                    m_Last %= m_Data.Length;
                    m_Pre %= m_Data.Length;
                }
            }

            public bool DeQueue()
            {
                if (IsEmpty()) return false;
                if ((m_Last - m_Pre == 0) && m_IsHave) m_IsHave = false;
                else m_Pre++;
                ClearIndex();
                return true;
            }

            public int Front()
            {
                if (IsEmpty()) return -1;
                return m_Data[m_Pre % (m_Data.Length)];
            }

            public int Rear()
            {
                if (IsEmpty()) return -1;
                return m_Data[m_Last % (m_Data.Length)];
            }

            public bool IsEmpty()
            {
                return ((m_Last - m_Pre) == 0) && !m_IsHave;
            }

            public bool IsFull()
            {
                if (m_Last == m_Pre && m_IsHave && m_Data.Length == 1) return true;
                if (m_Last == m_Pre) return false;
                return (m_Last - m_Pre) % (m_Data.Length - 1) == 0;
            }
        }
    }
}
